/**
 * Copyright � 2012 GestureSoft. ALL RIGHTS RESERVED.
 * This file contains proprietary and GestureSoft CONFIDENTIAL Information.
 * Use, disclosure or reproduction is prohibited.
 * 
 * @fileName ZipExtractor.as
 * @creationDate Aug 8, 2012
 * @author 
 * @version 1.0
 */
package com.gesturesoft.imultimax.model
{
	
	import com.gesturesoft.imultimax.events.CompleteEvent;
	import com.gesturesoft.imultimax.model.completor.Completor;
	import com.gesturesoft.imultimax.model.interfaces.IZipExtractor;
	import com.gesturesoft.imultimax.model.vo.AppVO;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.OutputProgressEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.FileFilter;
	import flash.utils.ByteArray;
	import flash.utils.CompressionAlgorithm;
	import flash.utils.Endian;
	
	import mx.collections.ArrayCollection;

	public class ZipExtractor extends Completor implements IZipExtractor
	{
		
		private var _assetDetails:ArrayCollection;
		private var _tmpFolder:File;
		private var source:String;
		private var fileName:String;
		private var targetpath:String;
		private var bytes:ByteArray=new ByteArray();
		private var assetCount:int = 0;
		
		public function ZipExtractor(val:ArrayCollection)
		{
			
			assetDetails = val;
			assetCount = assetDetails.length;
			
		}
		
		public function extract():void
		{
			
			assetCount -= 1;
			if( assetCount < 0 )
			{
				
				super.complete(this);
				return;
				
			}
				
			var appVO:AppVO = this.assetDetails[assetCount];
			
			var flNameLength:Number;
			var xfldLength:Number;
			var offset:Number;
			var compSize:Number;
			var uncompSize:Number;
			var compMethod:Number;
			var signature:Number;      
			var zfile:File = File.applicationStorageDirectory.resolvePath(appVO.name+"/assets.zip");
			trace(zfile.url)
			var zStream:FileStream = new FileStream();
			zStream.open(zfile, FileMode.READ);
			bytes.endian =  Endian.LITTLE_ENDIAN;
			
			while (zStream.position < zfile.size)
			{
				
				// read fixed metadata portion of local file header
				zStream.readBytes(bytes, 0, 30);
				bytes.position = 0;
				signature = bytes.readInt();
				// if no longer reading data files, quit
				if (signature != 0x04034b50)
				{
					
					break;
					
				}
				bytes.position = 8;
				compMethod = bytes.readByte();  // store compression method (8 == Deflate)
				offset = 0;                    // stores length of variable portion of metadata
				bytes.position = 26;           // offset to file name length
				flNameLength = bytes.readShort();    // store file name
				offset += flNameLength;     // add length of file name
				bytes.position = 28;        // offset to extra field length
				xfldLength = bytes.readShort();
				offset += xfldLength;    // add length of extra field
				// read variable length bytes between fixed-length header and compressed file data
				zStream.readBytes(bytes, 30, offset);
				bytes.position = 30;
				fileName = bytes.readUTFBytes(flNameLength); // read file name
				if(fileName.substr(fileName.length - 1, 1) != '/')
				{
					
					bytes.position = 18;
					compSize = bytes.readUnsignedInt(); // store size of compressed portion
					bytes.position = 22; // offset to uncompressed size
					uncompSize = bytes.readUnsignedInt(); // store uncompressed size
					
					// read compressed file to offset 0 of bytes; for uncompressed files
					// the compressed and uncompressed size is the same
					zStream.readBytes(bytes, 0, compSize);
					trace("Extracting file --->"+fileName);
					if (compMethod == 8 ) // if file is compressed, uncompress
					{
						
						bytes.uncompress(CompressionAlgorithm.DEFLATE);
						
						
					}
					writeFile( appVO.name , fileName, bytes); // call outFile() to write out the file
					trace( "out file: "+File( File.applicationStorageDirectory.resolvePath(appVO.name) ).url)
					
				}
				
			}
			
			if( assetCount >= 0 )
			{
				
				extract();
				
			}
			else
			{
				
				return;
				//super.complete();
				
			}
			
		}
		
		public function writeFile(baseDir:String,fileName:String,data:ByteArray):void 
		{
			
			var outFile:File=File.applicationStorageDirectory.resolvePath(baseDir+"/"+fileName);
			//outFile=outFile.resolvePath(baseDir+"/"+fileName);
			var outStream:FileStream=new FileStream();
			outStream.open(outFile,FileMode.UPDATE);
			
			outStream.writeBytes(data, 0, data.length);
			outStream.close();
			
		} 
		
		
		public function get assetDetails():ArrayCollection
		{
			
			return _assetDetails;
			
		}
		
		public function set assetDetails(val : ArrayCollection):void
		{
			
			_assetDetails = val;
			
		}
		
	}
	
}